package cn.changein.framework.fastDFS;

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.csource.common.MyException;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.TrackerServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Properties;

/**
 * TrackerServer 对象池
 * <p>
 *

 * @version 1.0
 * @date 2017-10-14 15:23
 */
@Component
public class TrackerServerPool {

    @Value("${fastdfs.file_server_addr}")
    private String file_server_addr;

    @Value("${fastdfs.http_secret_key}")
    private String http_secret_key;

    @Value("${fastdfs.connect_timeout_in_seconds}")
    private String connect_timeout_in_seconds;

    @Value("${fastdfs.network_timeout_in_seconds}")
    private String network_timeout_in_seconds;

    @Value("${fastdfs.charset}")
    private String charset;

    @Value("${fastdfs.http_anti_steal_token}")
    private String http_anti_steal_token;

    @Value("${fastdfs.http_tracker_http_port}")
    private String http_tracker_http_port;

    @Value("${fastdfs.tracker_servers}")
    private String tracker_servers;

    /**
     * org.slf4j.Logger
     */
    private static Logger logger = LoggerFactory.getLogger(TrackerServerPool.class);

    /**
     * TrackerServer 配置文件路径
     */
    private static final String FASTDFS_CONFIG_PATH = "config.properties";

    /**
     * 最大连接数 default 8.
     */
    private static int maxStorageConnection = 8;

    /**
     * TrackerServer 对象池.
     * GenericObjectPool 没有无参构造
     */
    private static GenericObjectPool<TrackerServer> trackerServerPool;

    private TrackerServerPool() {
    }

    @PostConstruct
    public GenericObjectPool<TrackerServer> getObjectPool() {
        if (trackerServerPool == null) {
            try {
                Properties properties = new Properties();
                properties.setProperty("fastdfs.file_server_addr", file_server_addr);
                properties.setProperty("fastdfs.http_secret_key", http_secret_key);
                properties.setProperty("fastdfs.connect_timeout_in_seconds", connect_timeout_in_seconds);
                properties.setProperty("fastdfs.network_timeout_in_seconds", network_timeout_in_seconds);
                properties.setProperty("fastdfs.charset", charset);
                properties.setProperty("fastdfs.http_anti_steal_token", http_anti_steal_token);
                properties.setProperty("fastdfs.http_tracker_http_port", http_tracker_http_port);
                properties.setProperty("fastdfs.tracker_servers", tracker_servers);
                // 加载配置文件
                ClientGlobal.initByProperties(properties);
            } catch (IOException | MyException e) {
                e.printStackTrace();
            }

            if (logger.isDebugEnabled()) {
                logger.debug("ClientGlobal configInfo: {}", ClientGlobal.configInfo());
            }

            // Pool配置
            GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
            poolConfig.setMinIdle(2);
            if (maxStorageConnection > 0) {
                poolConfig.setMaxTotal(maxStorageConnection);
            }

            trackerServerPool = new GenericObjectPool<>(new TrackerServerFactory(), poolConfig);
        }
        return trackerServerPool;
    }

    /**
     * 获取 TrackerServer
     *
     * @return TrackerServer
     * @throws FastDFSException
     */
    public TrackerServer borrowObject() throws FastDFSException {
        TrackerServer trackerServer = null;
        try {
            trackerServer = getObjectPool().borrowObject();
        } catch (Exception e) {
            e.printStackTrace();
            if (e instanceof FastDFSException) {
                throw (FastDFSException) e;
            }
        }
        return trackerServer;
    }

    /**
     * 回收 TrackerServer
     *
     * @param trackerServer 需要回收的 TrackerServer
     */
    public void returnObject(TrackerServer trackerServer) {

        getObjectPool().returnObject(trackerServer);
    }

}
